<template>
  <div id="CanvasToPdf">
    <canvas id="myCanvas" />
    <div class="flex justify-between">
      <div class="flex w-full flex-col items-center">
        <div class="flex w-full justify-between">
          <el-carousel :autoplay="false" class="w-full">
            <el-carousel-item>
              <div style="height: 500px" df-x-c>
                <img src="" id="preview1" style="height: 100%" />
              </div>
            </el-carousel-item>
            <el-carousel-item>
              <div style="height: 500px" df-x-c>
                <img src="" id="preview2" style="height: 100%" class="border border-black border-solid" />
              </div>
            </el-carousel-item>
          </el-carousel>
        </div>
        <el-button class="mt-5" type="primary" @click="save">
          <el-icon>
            <Download />
          </el-icon>
          下载证书
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import jsPDF from "jspdf"
import { nextTick, onMounted, PropType, ref } from "vue"
import { IGetStudentByCardIdResponseData } from "@/api/student/types/student"
import dayjs from "@/utils/day"
import { ElLoading } from "element-plus"
import jsZip from "jszip"
import FileSaver from "file-saver"
import { Download } from "@element-plus/icons-vue"
const props = defineProps({
  drawData: {
    type: Object as PropType<IGetStudentByCardIdResponseData | undefined>,
    required: true
  }
})
const pdfDoc = new jsPDF()

const canvasData = ref<{
  generateTime: {
    year: string
    month: string
    day: string
  }
  enrollmentTime: {
    year: string
    month: string
    day: string
  }
  graduateTime: {
    year: string
    month: string
    day: string
  }
  pdfs: Blob[]
  image1Data: {
    dataURL: string
  }
  image2Data: {
    dataURL: string
  }
}>({
  generateTime: {
    year: dayjs().year() + "",
    month: dayjs().format("MM"),
    day: dayjs().format("DD")
  },
  enrollmentTime: {
    year: dayjs(props.drawData?.enrollmentTime).year() + "",
    month: dayjs(props.drawData?.enrollmentTime).format("MM"),
    day: dayjs(props.drawData?.enrollmentTime).format("DD")
  },
  graduateTime: {
    year: dayjs(props.drawData?.graduateTime).year() + "",
    month: dayjs(props.drawData?.graduateTime).format("MM"),
    day: dayjs(props.drawData?.graduateTime).format("DD")
  },
  pdfs: [],
  image1Data: {
    dataURL: ""
  },
  image2Data: {
    dataURL: ""
  }
})

let canvas: null | HTMLCanvasElement = null
let ctx: CanvasRenderingContext2D | null = null
// 获取Canvas对象
onMounted(() => {
  const loading = ElLoading.service({
    text: "生成中...",
    fullscreen: true,
    body: true
  })
  canvas = document.getElementById("myCanvas") as HTMLCanvasElement
  // 创建画布上下文对象
  ctx = canvas.getContext("2d")

  nextTick(async () => {
    await setBackground(ctx, "/images/certificate1.png")
    await drawData1(ctx)
    await setBackground(ctx, "/images/certificate2.png")
    await drawData2(ctx)
    loading.close()
  })
})

const drawData1 = async (ctx: CanvasRenderingContext2D | null): Promise<void> => {
  if (!ctx || !canvas || !props.drawData) return
  drawText(ctx, props.drawData.name, "middle", 1330, 120, "#000")
  drawText(ctx, canvasData.value.generateTime.year, canvas!.width / 2 - 300, 3194, 55, "#000")
  drawText(ctx, canvasData.value.generateTime.month, canvas!.width / 2 + 10, 3194, 55, "#000")
  drawText(ctx, canvasData.value.generateTime.day, canvas!.width / 2 + 260, 3194, 55, "#000")
  drawText(ctx, props.drawData.projectName, "middle", 1750, 80, "#000")
  drawText(ctx, props.drawData.certificateNo, canvas!.width / 2 - 140, 2375, 65, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.year, canvas!.width / 2 - 434, 1903, 52, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.month, canvas!.width / 2 - 244, 1903, 52, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.day, canvas!.width / 2 - 128, 1903, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.year, canvas!.width / 2 + 70, 1903, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.month, canvas!.width / 2 + 253, 1903, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.day, canvas!.width / 2 + 375, 1903, 52, "#000")
  drawText(ctx, "陈涛", 580, 2800, 62, "#000")
  await drawImage(ctx, "/images/tx.jpeg", 1732, 914)
  const preview1 = document.getElementById("preview1") as HTMLImageElement
  const dataURL = getPreview(canvas)
  preview1.src = dataURL
  addPdf(dataURL)
  canvasData.value.image1Data.dataURL = dataURL
}

const drawData2 = async (ctx: CanvasRenderingContext2D | null): Promise<void> => {
  if (!ctx || !canvas || !props.drawData) return
  drawText(ctx, props.drawData.name, "middle", 1330, 120, "#000")
  drawText(ctx, canvasData.value.generateTime.year, canvas!.width / 2 - 300, 3194, 55, "#000")
  drawText(ctx, canvasData.value.generateTime.month, canvas!.width / 2 + 10, 3194, 55, "#000")
  drawText(ctx, canvasData.value.generateTime.day, canvas!.width / 2 + 260, 3194, 55, "#000")
  drawText(ctx, props.drawData.projectName, "middle", 1750, 80, "#000")
  drawText(ctx, props.drawData.certificateNo, canvas!.width / 2 - 140, 2375, 65, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.year, canvas!.width / 2 - 434, 1903, 52, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.month, canvas!.width / 2 - 244, 1903, 52, "#000")
  drawText(ctx, canvasData.value.enrollmentTime.day, canvas!.width / 2 - 128, 1903, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.year, canvas!.width / 2 + 70, 1903, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.month, canvas!.width / 2 + 253, 1903, 52, "#000")
  drawText(ctx, canvasData.value.graduateTime.day, canvas!.width / 2 + 375, 1903, 52, "#000")
  drawText(ctx, "陈涛", 580, 2800, 62, "#000")
  await drawImage(ctx, "/images/tx.jpeg", 1732, 914)
  const preview = document.getElementById("preview2") as HTMLImageElement
  const dataURL = getPreview(canvas)
  addPdf(dataURL)
  preview.src = dataURL
  canvasData.value.image2Data.dataURL = dataURL
}

const zip = new jsZip()
const save = () => {
  canvasData.value.pdfs.forEach((pdf, index) => {
    zip.file(`证书${index + 1}.pdf`, pdf)
  })
  zip.generateAsync({ type: "blob" }).then((content) => {
    FileSaver.saveAs(
      content,
      props.drawData!.graduateTime + props.drawData!.name + props.drawData!.projectName + "结业证书.zip"
    )
  })
}
const getPreview = (canvas: HTMLCanvasElement) => {
  // 将Canvas转换为图片数据
  return canvas.toDataURL("image/jpeg", 1.0)
}

const addPdf = (dataURL: string) => {
  pdfDoc.addImage(dataURL, "JPEG", 0, 0, 210, 297)
  const blob = pdfDoc.output("blob")
  canvasData.value.pdfs.push(blob)
}

const setBackground = (ctx: CanvasRenderingContext2D | null, bgImageUrl: string) => {
  if (!ctx) return
  return new Promise((resolve) => {
    const image = new Image()
    image.src = bgImageUrl
    image.onload = () => {
      if (canvas) {
        canvas.width = image.width
        canvas.height = image.height
      }
      ctx.drawImage(image, 0, 0)
      resolve(true)
    }
  })
}

const drawText = (
  ctx: CanvasRenderingContext2D,
  text: string,
  x: number | "middle",
  y: number,
  size: number,
  color = "#000"
) => {
  ctx.font = `${size}px 黑体 bold`
  ctx.fillStyle = color
  if (x === "middle") {
    const textWidth = ctx.measureText(text).width
    const canvasWidth = canvas!.width
    const xPosition = canvasWidth / 2 - textWidth / 2
    ctx.fillText(text, xPosition, y)
  } else {
    ctx.fillText(text, x, y)
  }
}
const drawImage = (ctx: CanvasRenderingContext2D, imageUrl: string, x: number, y: number) => {
  return new Promise((resolve) => {
    const image = new Image()
    image.src = imageUrl
    image.onload = () => {
      ctx.drawImage(image, x, y, 350, 534)
      resolve(true)
    }
  })
}
</script>

<style scoped>
canvas {
  width: 0;
  height: 0;
}
:deep(.el-carousel__container) {
  height: 500px;
}
</style>
